package com.yx.outSourcing.service.impl;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.yx.outSourcing.R.Result;
import com.yx.outSourcing.entity.dto.OutsourcingPersonDTO;
import com.yx.outSourcing.entity.po.AccessApplication;
import com.yx.outSourcing.entity.po.OutsourcingPerson;
import com.yx.outSourcing.entity.vo.OutsourcingPersonVO;
import com.yx.outSourcing.enums.PersonStatus;
import com.yx.outSourcing.mapper.AccessApplicationMapper;
import com.yx.outSourcing.mapper.OutsourcingPersonMapper;
import com.yx.outSourcing.service.IOutsourcingPersonService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 外协人员信息表 服务实现类
 * </p>
 *
 * @author zcc
 * @since 2025-07-29
 */


@Service
public class OutsourcingPersonServiceImpl extends ServiceImpl<OutsourcingPersonMapper, OutsourcingPerson> implements IOutsourcingPersonService {

    @Autowired
    private OutsourcingPersonMapper outsourcingPersonMapper;

    @Autowired
    private AccessApplicationMapper accessApplicationMapper;

    @Override
    public Long addOutsourcingPerson(OutsourcingPersonDTO dto) {
        // 1. 根据申请单号查询申请单
        AccessApplication application = accessApplicationMapper.selectOne(
                new LambdaQueryWrapper<AccessApplication>()
                        .eq(AccessApplication::getId, dto.getAppId())
        );
        if (application == null) {
//            return Result.error("申请单不存在");
            throw new RuntimeException("申请单不存在");
        }

        // 2. 校验当前人员数量是否超过申请人数
        long currentPersonCount = outsourcingPersonMapper.selectCount(
                new LambdaQueryWrapper<OutsourcingPerson>()
                        .eq(OutsourcingPerson::getAppId, application.getId())
        );
        if (currentPersonCount >= application.getEntryCount()) {
//            return Result.error("外协人员数量已超过申请人数限制");
            throw new RuntimeException("外协人员数量已超过申请人数限制");
        }

        // 3. 校验身份证号是否已存在
        long idCardCount = outsourcingPersonMapper.selectCount(
                new LambdaQueryWrapper<OutsourcingPerson>()
                        .eq(OutsourcingPerson::getIdCard, dto.getIdCard())
        );
        if (idCardCount > 0) {
//            return Result.error();
            throw new RuntimeException("身份证号已存在");
        }

        // 4. 创建人员记录
        OutsourcingPerson person = new OutsourcingPerson();
        BeanUtils.copyProperties(dto, person);
        person.setAppId(application.getId());
        person.setStatus(PersonStatus.NORMAL); // 状态：1-正常
        person.setCreateTime(LocalDateTime.now());
        person.setUpdateTime(LocalDateTime.now());
        person.setCreatedBy(dto.getCreatedBy());
        person.setUpdatedBy(dto.getCreatedBy());

        // 5. 保存到数据库
        outsourcingPersonMapper.insert(person);

        return person.getPerId();
    }

    @Override
    public boolean updateOutPerson(Long id, OutsourcingPersonDTO dto) {
        // 1. 检查要更新的外协人员是否存在
        OutsourcingPerson existingPerson = outsourcingPersonMapper.selectById(id);
        if (existingPerson == null) {
            throw new RuntimeException("外协人员不存在");
        }

        // 2. 根据申请单号查询申请单
        AccessApplication application = accessApplicationMapper.selectOne(
                new LambdaQueryWrapper<AccessApplication>()
                        .eq(AccessApplication::getId, dto.getAppId())
        );
        if (application == null) {
            throw new RuntimeException("申请单不存在");
        }

        // 3. 校验身份证号是否已被其他人员使用
        long idCardCount = outsourcingPersonMapper.selectCount(
                new LambdaQueryWrapper<OutsourcingPerson>()
                        .eq(OutsourcingPerson::getIdCard, dto.getIdCard())
                        .ne(OutsourcingPerson::getPerId, id) // 排除自己
        );
        if (idCardCount > 0) {
            throw new RuntimeException("身份证号已存在");
        }

        // 4. 更新人员记录
        OutsourcingPerson personToUpdate = new OutsourcingPerson();
        BeanUtils.copyProperties(dto, personToUpdate);
        personToUpdate.setPerId(id); // 设置主键
        personToUpdate.setAppId(application.getId());
        personToUpdate.setUpdateTime(LocalDateTime.now());
        personToUpdate.setUpdatedBy(dto.getCreatedBy()); // 使用dto中的createdBy作为updatedBy

        // 5. 执行更新操作
        return this.updateById(personToUpdate);
    }


    @Override
    public Page<OutsourcingPersonVO> queryPersonList(String name, String idCard, String companyName,
                                                     String startDate, String endDate, Integer status,
                                                     Integer pageNum, Integer pageSize) {
        try {
            // 1. 构建查询条件
            LambdaQueryWrapper<OutsourcingPerson> queryWrapper =
                    buildQueryWrapper(name, idCard, companyName, startDate, endDate, status);

            // 2. 执行分页查询
            Page<OutsourcingPerson> personPage = queryPersonPage(queryWrapper, pageNum, pageSize);

            // 3. 转换为VO
            IPage<OutsourcingPersonVO> convertedPage = personPage.convert(this::convertToVO);
            Page<OutsourcingPersonVO> resultPage = new Page<>(convertedPage.getCurrent(), convertedPage.getSize(), convertedPage.getTotal());
            resultPage.setRecords(convertedPage.getRecords());

            return resultPage;

        } catch (RuntimeException e) {
            // 处理已知业务异常
            return new Page<>(pageNum, pageSize, 0);
        } catch (Exception e) {
            // 记录未知异常
            log.error("查询外协人员列表异常", e);
            throw new RuntimeException("查询失败");
        }
    }


    /**
     * 查询条件构建
     */
    private LambdaQueryWrapper<OutsourcingPerson> buildQueryWrapper(String name, String idCard,
                                                                    String companyName, String startDate,
                                                                    String endDate, Integer status) {
        LambdaQueryWrapper<OutsourcingPerson> queryWrapper = new LambdaQueryWrapper<>();

        // 基础条件
        queryWrapper.eq(StringUtils.isNotBlank(name), OutsourcingPerson::getUserName, name)
                .eq(StringUtils.isNotBlank(idCard), OutsourcingPerson::getIdCard, idCard)
                .eq(status != null, OutsourcingPerson::getStatus, status);

        // 时间范围
        if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
            queryWrapper.between(OutsourcingPerson::getEntryTime, startDate, endDate);
        }

        // 公司名称查询
        if (StringUtils.isNotBlank(companyName)) {
            List<Long> appIds = findApplicationIdsByCompanyName(companyName.trim());
            if (!appIds.isEmpty()) {
                queryWrapper.in(OutsourcingPerson::getAppId, appIds);
            } else {
                throw new RuntimeException("未找到匹配的公司");
            }
        }

        return queryWrapper;
    }

    private List<Long> findApplicationIdsByCompanyName(String companyName) {
        return Db.lambdaQuery(AccessApplication.class)
                .select(AccessApplication::getId)
                .like(AccessApplication::getOutUnit, companyName)
                .list()
                .stream()
                .map(AccessApplication::getId)
                .distinct()
                .collect(Collectors.toList());
    }

    /**
     * 分页查询
     */
    private Page<OutsourcingPerson> queryPersonPage(LambdaQueryWrapper<OutsourcingPerson> queryWrapper,
                                                    int pageNum, int pageSize) {
        // 先查询总数
        long total = outsourcingPersonMapper.selectCount(queryWrapper);

        // 无数据时快速返回
        if (total == 0) {
            return new Page<>(pageNum, pageSize, total);
        }

        // 设置分页参数
        Page<OutsourcingPerson> page = new Page<>(pageNum, pageSize, total);
        queryWrapper.last("LIMIT " + (pageNum - 1) * pageSize + "," + pageSize);

        // 执行查询
        List<OutsourcingPerson> records = outsourcingPersonMapper.selectList(queryWrapper);
        page.setRecords(records);

        return page;
    }

    /**
     * 转换为VO
     */
    private OutsourcingPersonVO convertToVO(OutsourcingPerson person) {
        OutsourcingPersonVO vo = new OutsourcingPersonVO();
        BeanUtils.copyProperties(person, vo);

        // 查询关联信息
        Optional.ofNullable(person.getAppId())
                .flatMap(appId -> Optional.ofNullable(
                        Db.lambdaQuery(AccessApplication.class)
                                .eq(AccessApplication::getId, appId)
                                .one()
                ))
                .ifPresent(app -> {
                    vo.setCompanyName(app.getOutUnit());
                    vo.setWorkArea(app.getArea());
                });

        // 计算照片数
        vo.setPhotoCount(
                (int) Stream.of(person.getIdCardFront(), person.getIdCardBack(), person.getPortraitPhoto())
                        .filter(StringUtils::isNotBlank)
                        .count()
        );

        return vo;
    }

}
